package com.xjrsoft.module.interfaceManager.service.impl;

import cn.hutool.db.Entity;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xjrsoft.common.Enum.EnabledMarkEnum;
import com.xjrsoft.common.allenum.LogCategoryEnum;
import com.xjrsoft.common.allenum.OperateTypeEnum;
import com.xjrsoft.common.allenum.RequestMethodEnum;
import com.xjrsoft.common.config.ServerConfig;
import com.xjrsoft.common.dbmodel.DbExecutor;
import com.xjrsoft.common.result.Response;
import com.xjrsoft.common.utils.IpUtil;
import com.xjrsoft.core.secure.utils.SecureUtil;
import com.xjrsoft.core.tool.utils.*;
import com.xjrsoft.module.base.entity.XjrBaseLog;
import com.xjrsoft.module.base.service.IXjrBaseLogService;
import com.xjrsoft.module.base.utils.LogUtil;
import com.xjrsoft.module.interfaceManager.constant.SchemaConst;
import com.xjrsoft.module.interfaceManager.dto.AddInfoDto;
import com.xjrsoft.module.interfaceManager.dto.AddOutputDto;
import com.xjrsoft.module.interfaceManager.dto.AddParamDto;
import com.xjrsoft.module.interfaceManager.entity.XjrInterfaceInfo;
import com.xjrsoft.module.interfaceManager.entity.XjrInterfaceOutput;
import com.xjrsoft.module.interfaceManager.entity.XjrInterfaceParams;
import com.xjrsoft.module.interfaceManager.entity.XjrInterfaceSchema;
import com.xjrsoft.module.interfaceManager.mapper.XjrInterfaceInfoMapper;
import com.xjrsoft.module.interfaceManager.service.*;
import okhttp3.HttpUrl;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.sql.SQLException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Pattern;

/**
 * <p>
 * 接口信息管理（框架内部接口） 服务实现类
 * </p>
 *
 * @author tzx
 * @since 2022-01-18
 */
@Service
public class XjrInterfaceInfoServiceImpl extends ServiceImpl<XjrInterfaceInfoMapper, XjrInterfaceInfo> implements IXjrInterfaceInfoService {

    @Autowired
    private IXjrInterfaceParamsService paramsService;

    @Autowired
    private IXjrInterfaceSchemaService schemaService;

    @Autowired
    private IXjrInterfaceOutputService outputService;

    @Autowired
    private IXjrInterfaceAuthService authService;

    @Autowired
    private DbExecutor dbExecutor;

    @Autowired
    private ServerConfig serverConfig;

    @Autowired
    private IXjrBaseLogService logService;

    @Override
    public Response execute(String id, Map<String, String> paramMap, HttpServletRequest request) throws SQLException {
        XjrInterfaceInfo info = this.getById(id);
        // 权限验证
        if (!authService.checkAuth(id,request)) {
            return Response.notOk("接口未授权: " + info.getName());
        }
        if (info != null) {
            if (info.getEnabledMark() == EnabledMarkEnum.NOENABLED.getCode()) {
                return Response.notOk("当前接口已经禁用！");
            }
            String message = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "开始执行";
            addLog(1, info.getName(), message);

            //是否为系统接口
            if (info.getIsCustomize() == 0) {
                List<XjrInterfaceParams> paramsList = paramsService.list(Wrappers.<XjrInterfaceParams>query().lambda().eq(XjrInterfaceParams::getInfoId, id));
                List<XjrInterfaceOutput> outputList = outputService.list(Wrappers.<XjrInterfaceOutput>query().lambda().eq(XjrInterfaceOutput::getInfoId, id));
                //系统接口参数验证
                if (!checkParamValue(paramsList, paramMap)) {
                    return Response.notOk("当前接口请求参数错误！");
                }

                if (info.getRequestMethod() == RequestMethodEnum.GET.getCode()) {
                    return executeGet(info, paramsList, outputList, paramMap, request);
                }

                if (info.getRequestMethod() == RequestMethodEnum.POST.getCode()) {
                    return executePost(info, paramsList, outputList, paramMap, request);
                }

                if (info.getRequestMethod() == RequestMethodEnum.PUT.getCode()) {
                    return executePut(info, paramsList, outputList, paramMap, request);
                }

                if (info.getRequestMethod() == RequestMethodEnum.DELETE.getCode()) {
                    return executeDelete(info, paramsList, outputList, paramMap, request);
                }
            }
            //如果是自定义接口
            else {
                XjrInterfaceSchema schema = schemaService.getOne(Wrappers.<XjrInterfaceSchema>query().lambda().in(XjrInterfaceSchema::getInfoId, id));
                String schemaString = Optional.ofNullable(schema.getJsonSchema()).orElse("");
                if (StringUtil.isEmpty(schemaString)) {
                    return Response.notOk("当前接口配置错误！");
                }

                JSONObject allObj = JSONObject.parseObject(schemaString);

                //获取到所有变量配置
                JSONArray varArray = allObj.getJSONArray(SchemaConst.VAR_SETTING);
                //获取到所有切面配置
                JSONArray aopArray = allObj.getJSONArray(SchemaConst.AOP_SETTING);
                //获取到所有出参配置
                JSONArray outputArray = allObj.getJSONArray(SchemaConst.OUTPUT_SETTING);
                //获取到所有入参配置
                JSONArray inputArray = allObj.getJSONArray(SchemaConst.INPUT_SETTING);

                //
                Boolean checkParamNodeLog = false;
                for (int i = 0; i < aopArray.size(); i++) {
                    JSONObject aopObj = aopArray.getJSONObject(i);
                    Integer nodeLifeCycleType = aopObj.getInteger("nodeLifeCycleType");
                    Boolean isCustom = aopObj.getBoolean("isCustom");
                    if (nodeLifeCycleType != null && isCustom != null && nodeLifeCycleType == 0 && !isCustom) {
                        //是验证参数节点
                        checkParamNodeLog = aopObj.getBoolean("nodeLog");
                        break;
                    }
                }
                if (!checkCustomizeParamValue(inputArray, paramMap, checkParamNodeLog, info.getName())) {
                    return Response.notOk("当前接口请求参数错误！");
                }

                Map<String, Object> varMaps = new HashMap<>();
                for (int i = 0; i < varArray.size(); i++) {
                    JSONObject varObj = varArray.getJSONObject(i);
                    Integer varType = varObj.getInteger(SchemaConst.VAR_TYPE);
                    // 如果是普通的值
                    if (varType == 0) {
                        varMaps.put(varObj.getString(SchemaConst.VAR_CODE), varObj.getString(SchemaConst.VAR_VALUE));
                    }
                    // 如果是参数
                    if (varType == 1) {
                        JSONArray valueArray = varObj.getJSONArray(SchemaConst.VAR_VALUE);
                        JSONObject jsonObject = valueArray.getJSONObject(0);
                        Integer parentId = jsonObject.getInteger(SchemaConst.PARENT_ID);
                        String param = "";
                        //如果parentId 是0  则代表使用接口入参
                        if (parentId == 0) {
                            param = paramMap.get(jsonObject.getString(SchemaConst.VARVALUE_LABEL));
                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), param);
                        }
                        if (parentId == 2) {
                            param = jsonObject.getString(SchemaConst.VARVALUE_VALUE);
                            switch (param) {
                                case "0": //yyyy-MM-dd HH:mm:ss
                                    DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format0));
                                    break;
                                case "1":// yyyy-MM-dd hh:mm:ss
                                    DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format1));
                                    break;
                                case "2":// yyyy-MM-dd
                                    DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format2));
                                    break;
                                case "3":// HH:mm:ss
                                    DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format3));
                                    break;
                                case "4":// hh:mm:ss
                                    DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format4));
                                    break;
                            }
                        }

                    }
                    // 如果变量是sql语句
                    if (varType == 2) {
                        JSONObject dbObj = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                        String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                        String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                        String field = dbObj.getString(SchemaConst.SQL_FIELD);
                        List<Entity> maps = dbExecutor.executeQuery(dbId, replaceSqlParam(querySql, paramMap, varMaps));
                        //只去第一条的 field字段
                        if (maps.size() > 0) {
                            Object sqlResult = maps.get(0).get(field);
                            //吧code  跟值  对应 存到map  后续要用
                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), sqlResult);
                        }
                    }
                    // 如果是请求接口 默认套娃 再次请求此接口
                    if (varType == 3) {
                        JSONObject varValueObject = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                        String infoId = varValueObject.getString(SchemaConst.INTERFACE_INFOID);
                        String infoName=this.getById(infoId).getName();
                        OkHttpClient client = new OkHttpClient();

                        //获取到当前请求的host 用于套娃请求
                        String requestURL = request.getRequestURL().toString();
                        String host = serverConfig.getLocalUrl();
                        HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                        Request.Builder url = new Request.Builder().url(builder.build());

                        //转发请求头继续塞入
                        Enumeration<String> headers = request.getHeaderNames();
                        while (headers.hasMoreElements()) {
                            String key = headers.nextElement();
                            url.addHeader(key, request.getHeader(key));
                        }
                        //拼接参数
                        JSONArray paramsArray = varObj.getJSONObject(SchemaConst.VAR_VALUE).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                        Map<String, String> paramsMap = new HashMap<>();
                        if (CollectionUtil.isNotEmpty(paramsArray)) {
                            for (int idx = 0; idx < paramsArray.size(); idx++) {
                                JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                //如果变量配置类型为0   默认value  就是值
                                if (type == 0) {
                                    paramsMap.put(key, value);
                                } else {
                                    //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                    String param = paramMap.get(value);
                                    if (StringUtil.isNotBlank(param)) {
                                        paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                    } else {
                                        //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                        param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                        switch (param) {
                                            case "0": //yyyy-MM-dd HH:mm:ss
                                                DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                paramsMap.put(key, LocalDateTime.now().format(format0));
                                                break;
                                            case "1":// yyyy-MM-dd hh:mm:ss
                                                DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                paramsMap.put(key, LocalDateTime.now().format(format1));
                                                break;
                                            case "2":// yyyy-MM-dd
                                                DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                paramsMap.put(key, LocalDateTime.now().format(format2));
                                                break;
                                            case "3":// HH:mm:ss
                                                DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                paramsMap.put(key, LocalDateTime.now().format(format3));
                                                break;
                                            case "4":// hh:mm:ss
                                                DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                paramsMap.put(key, LocalDateTime.now().format(format4));
                                                break;
                                        }
                                    }
                                }
                            }
                        }

                        MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                        okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                        Request req = url.post(body).build();
                        try (okhttp3.Response response = client.newCall(req).execute()) {
                            String responseBody = Objects.requireNonNull(response.body()).string();
                            if (!response.isSuccessful()) {
                                // ... handle failed request
                                return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                            }
                            // ... do something with response

                            JSONObject jsonObject = JSONObject.parseObject(responseBody);
                            if (jsonObject != null) {
                                Integer code = (Integer) jsonObject.get("code");
                                if (code == 0) {
                                    JSONObject data = jsonObject.getJSONObject("data");
                                    String varCode = varObj.getString(SchemaConst.VAR_CODE);
                                    JSONObject varValue = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                    String interfaceField = varValue.getString(SchemaConst.INTERFACE_FIELD);
                                    varMaps.put(varCode, data.get(interfaceField));
                                } else {
                                    return Response.notOk("接口名:" + infoName  + " ,请求错误！错误原因"+responseBody);
                                }
                            } else {
                                return Response.notOk("接口名:" + infoName    + " ,请求错误！错误原因"+responseBody);
                            }
                        } catch (IOException e) {
                            // ... handle IO exception
                            return Response.notOk("接口名:" + infoName  + " ,请求错误！错误原因"+e.getMessage());
                        }
                    }
                }

                //验证期间的节点
                JSONArray aopVolidateArray = new JSONArray();
                //执行期间的节点
                JSONArray aopExecuteArray = new JSONArray();
                //执行结束的节点
                JSONArray aopEndArray = new JSONArray();

                for (int i = 0; i < aopArray.size(); i++) {
                    Integer lifecycleType = aopArray.getJSONObject(i).getInteger(SchemaConst.AOP_NODELIFECYCLETYPE);
                    Boolean isCustom = aopArray.getJSONObject(i).getBoolean(SchemaConst.IS_CUSTOM);
                    if (lifecycleType == null || (isCustom != null && !isCustom)) {
                        continue;
                    }

                    //获取nodeType == 0 的节点  这些节点将会在数据验证的时候执行
                    if (lifecycleType == 0) {
                        aopVolidateArray.add(aopArray.getJSONObject(i));
                    }
                    //获取nodeType == 1 的节点  这些节点将会在接口执行的时候执行
                    if (lifecycleType == 1) {
                        aopExecuteArray.add(aopArray.getJSONObject(i));
                    }
                    //获取nodeType == 2 的节点  这些节点将会在执行结束执行
                    if (lifecycleType == 2) {
                        aopEndArray.add(aopArray.getJSONObject(i));
                    }
                }

                //验证之后执行变量赋值
                for (int i = 0; i < aopVolidateArray.size(); i++) {
                    //获取到当前节点变量赋值
                    JSONArray varAssignArray = aopVolidateArray.getJSONObject(i).getJSONArray(SchemaConst.AOP_NODEVARASSIGN);
                    String nodeName = aopVolidateArray.getJSONObject(i).getString(SchemaConst.AOP_NODENAME);
                    Boolean aopNodeLoge = aopVolidateArray.getJSONObject(i).getBoolean(SchemaConst.AOP_NODELOG);
                    if (aopNodeLoge != null && aopNodeLoge) {
                        String aopMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + nodeName + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                        addLog(1, nodeName, aopMessage);
                    }
                    if (varAssignArray != null && varAssignArray.size() > 0) {
                        for (int index = 0; index < varAssignArray.size(); index++) {
                            JSONObject varObj = varAssignArray.getJSONObject(index);
                            Integer varType = varObj.getInteger(SchemaConst.VAR_TYPE);
                            String varCode = varObj.getString(SchemaConst.VAR_CODE);
                            if (aopNodeLoge != null && aopNodeLoge) {
                                String varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                                addLog(1, nodeName, varMessage);
                            }
                            // 如果是普通的值
                            if (varType == 0) {
                                varMaps.put(varCode, varObj.getString(SchemaConst.VAR_VALUE));
                            }
                            // 如果是参数
                            if (varType == 1) {
                                JSONArray varValueArray = varObj.getJSONArray(SchemaConst.VAR_VALUE);
                                JSONObject varValue = varValueArray.getJSONObject(0);
                                Integer parentId = varValue.getInteger(SchemaConst.PARENT_ID);
                                //根据配置的参数code  如果code 能从参数里面知道相应的key  就使用的是参数值 如果找不到 则是 使用系统时间的值
                                if (parentId == 0) {
                                    String inputCode = varValue.getString(SchemaConst.VARVALUE_LABEL);
                                    varMaps.put(varCode, paramMap.get(inputCode));
                                } else {
                                    switch (varValue.getInteger(SchemaConst.VARVALUE_VALUE)) {
                                        case 0: //yyyy-MM-dd HH:mm:ss
                                            DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                            varMaps.put(varCode, LocalDateTime.now().format(format0));
                                            break;
                                        case 1:// yyyy-MM-dd hh:mm:ss
                                            DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                            varMaps.put(varCode, LocalDateTime.now().format(format1));
                                            break;
                                        case 2:// yyyy-MM-dd
                                            DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                            varMaps.put(varCode, LocalDateTime.now().format(format2));
                                            break;
                                        case 3:// HH:mm:ss
                                            DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                            varMaps.put(varCode, LocalDateTime.now().format(format3));
                                            break;
                                        case 4:// hh:mm:ss
                                            DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                            varMaps.put(varCode, LocalDateTime.now().format(format4));
                                            break;
                                    }
                                }
                            }
                            // 如果变量是sql语句
                            if (varType == 2) {
                                JSONObject dbObj = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                                String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                                String field = dbObj.getString(SchemaConst.SQL_FIELD);
                                List<Entity> maps = new ArrayList<>();
                                try {
                                    maps = dbExecutor.executeQuery(dbId, replaceSqlParam(querySql, paramMap, varMaps));
                                } catch (Exception e) {
                                    if (aopNodeLoge != null && aopNodeLoge) {
                                        String varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因: " + e.getMessage();
                                        addLog(-1, nodeName, varMessage);
                                        return Response.notOk("sql" + querySql + "执行错误,错误原因:" + e.getMessage());
                                    }
                                }
                                //只去第一条的 field字段
                                if (maps.size() > 0) {
                                    Object sqlResult = maps.get(0).get(field);
                                    //把code  跟值  对应 存到map  后续要用
                                    varMaps.put(varCode, sqlResult);
                                }
                            }
                            // 如果是请求接口 默认套娃 再次请求此接口
                            if (varType == 3) {

                                JSONObject varValueObject = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                String infoId = varValueObject.getString(SchemaConst.INTERFACE_INFOID);
                                String infoName=this.getById(infoId).getName();
                                OkHttpClient client = new OkHttpClient();

                                //获取到当前请求的host 用于套娃请求
                                String requestURL = request.getRequestURL().toString();
                                String host = serverConfig.getLocalUrl();

                                HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                                Request.Builder url = new Request.Builder().url(builder.build());

                                //转发请求头继续塞入
                                Enumeration<String> headers = request.getHeaderNames();
                                while (headers.hasMoreElements()) {
                                    String key = headers.nextElement();
                                    url.addHeader(key, request.getHeader(key));
                                }
                                //拼接参数
                                JSONArray paramsArray = varObj.getJSONObject(SchemaConst.VAR_VALUE).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                                Map<String, String> paramsMap = new HashMap<>();
                                if (CollectionUtil.isNotEmpty(paramsArray)) {
                                    for (int idx = 0; idx < paramsArray.size(); idx++) {
                                        JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                        Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                        String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                        String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                        //如果变量配置类型为0   默认value  就是值
                                        if (type == 0) {
                                            paramsMap.put(key, value);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                            String param = paramMap.get(paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_LABEL));
                                            if (StringUtil.isNotBlank(param)) {
                                                paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                            } else {
                                                //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                                param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                                switch (param) {
                                                    case "0": //yyyy-MM-dd HH:mm:ss
                                                        DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format0));
                                                        break;
                                                    case "1":// yyyy-MM-dd hh:mm:ss
                                                        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format1));
                                                        break;
                                                    case "2":// yyyy-MM-dd
                                                        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                        paramsMap.put(key, LocalDateTime.now().format(format2));
                                                        break;
                                                    case "3":// HH:mm:ss
                                                        DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format3));
                                                        break;
                                                    case "4":// hh:mm:ss
                                                        DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format4));
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                }

                                MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                                Request req = url.post(body).build();
                                String varMessage = "";
                                Integer executeResult = -1;
                                try (okhttp3.Response response = client.newCall(req).execute()) {
                                    String responseBody = Objects.requireNonNull(response.body()).string();
                                    if (!response.isSuccessful()) {
                                        // ... handle failed request
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+responseBody;
                                        if (aopNodeLoge) addLog(executeResult, info.getName(), varMessage);
                                        return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                                    }
                                    // ... do something with response
                                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                    if (jsonObject != null) {
                                        Integer code = (Integer) jsonObject.get("code");
                                        if (code == 0) {
                                            JSONObject data = jsonObject.getJSONObject("data");
                                            JSONObject varValue = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                            String interfaceField = varValue.getString(SchemaConst.INTERFACE_FIELD);
                                            varMaps.put(varCode, data.get(interfaceField));
                                        } else {
                                            varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！" + responseBody;
                                            if (aopNodeLoge) addLog(executeResult, info.getName(), varMessage);
                                            return Response.notOk("接口名:" +infoName+" ,请求错误！错误原因"+responseBody);
                                        }
                                    } else {
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+responseBody;
                                        if (aopNodeLoge) addLog(executeResult, info.getName(), varMessage);
                                        return Response.notOk("接口名:" +infoName+" ,请求错误！错误原因"+responseBody);
                                    }
                                } catch (IOException e) {
                                    // ... handle IO exception
                                    varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+e.getMessage();
                                    if (aopNodeLoge) addLog(executeResult, info.getName(), varMessage);
                                    return Response.notOk("接口名:" +infoName+" ,请求错误！错误原因"+e.getMessage());
                                }
                            }
                            String varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "成功";
                            if (aopNodeLoge) addLog(1, info.getName(), varMessage);
                        }
                    }

                    //获取到当前节点所要执行的处理
                    JSONArray processArray = aopVolidateArray.getJSONObject(i).getJSONArray(SchemaConst.AOP_PROCESS);
                    if (processArray != null && processArray.size() > 0) {
                        for (int index = 0; index < processArray.size(); index++) {
                            JSONObject process = processArray.getJSONObject(index);
                            Boolean processLog = process.getBoolean(SchemaConst.PROCESS_LOG);
                            String showSetting = process.getString(SchemaConst.SHOW_SETTING);
                            if (processLog) {
                                String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                                addLog(1, nodeName, porcessStartMessage);
                            }
                            Integer processType = process.getInteger(SchemaConst.PROCESS_TYPE);
                            //type ==0  是执行sql
                            if (processType == 1) {
                                JSONObject dbObj = process.getJSONObject(SchemaConst.PROCESS_SETTING);
                                String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                                String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                                String field = dbObj.getString(SchemaConst.SQL_FIELD);
                                String sqlStr = replaceSqlParam(querySql, paramMap, varMaps);
                                try {
                                    String sqlTtype = sqlStr.substring(0, 6);
                                    if (StringUtil.equalsIgnoreCase(sqlTtype, "select")) {
                                        dbExecutor.executeQuery(dbId, sqlStr);
                                    } else {
                                        dbExecutor.batchExecuteNonParam(dbId, sqlStr);
                                    }
                                } catch (Exception e) {
                                    if (processLog) {
                                        String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因:" + e.getMessage();
                                        addLog(-1, nodeName, porcessStartMessage);
                                        return Response.notOk("sql" + querySql + "执行错误,错误原因:" + e.getMessage());
                                    }
                                }
                                if (processLog) {
                                    String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                                    addLog(1, nodeName, porcessStartMessage);
                                }
                            }
                            // type == 1 是请求api
                            if (processType == 0) {
                                String infoId = process.getJSONObject(SchemaConst.PROCESS_SETTING).getString(SchemaConst.INTERFACE_INFOID);
                                String infoName=this.getById(infoId).getName();
                                OkHttpClient client = new OkHttpClient();
                                //获取到当前请求的host 用于套娃请求
                                String requestURL = request.getRequestURL().toString();
                                String host = serverConfig.getLocalUrl();
                                HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                                Request.Builder url = new Request.Builder().url(builder.build());

                                //转发请求头继续塞入
                                Enumeration<String> headers = request.getHeaderNames();
                                while (headers.hasMoreElements()) {
                                    String key = headers.nextElement();
                                    url.addHeader(key, request.getHeader(key));
                                }
                                //拼接参数
                                JSONArray paramsArray = process.getJSONObject(SchemaConst.PROCESS_SETTING).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                                Map<String, String> paramsMap = new HashMap<>();
                                if (CollectionUtil.isNotEmpty(paramsArray)) {
                                    for (int idx = 0; idx < paramsArray.size(); idx++) {
                                        JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                        Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                        String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                        String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                        //如果变量配置类型为0   默认value  就是值
                                        if (type == 0) {
                                            paramsMap.put(key, value);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                            String param = paramMap.get(value);
                                            if (StringUtil.isNotBlank(param)) {
                                                paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                            } else {
                                                param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                                //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                                switch (param) {
                                                    case "0": //yyyy-MM-dd HH:mm:ss
                                                        DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format0));
                                                        break;
                                                    case "1":// yyyy-MM-dd hh:mm:ss
                                                        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format1));
                                                        break;
                                                    case "2":// yyyy-MM-dd
                                                        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                        paramsMap.put(key, LocalDateTime.now().format(format2));
                                                        break;
                                                    case "3":// HH:mm:ss
                                                        DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format3));
                                                        break;
                                                    case "4":// hh:mm:ss
                                                        DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format4));
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                }

                                MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                                Request req = url.post(body).build();
                                Integer executeResult = -1;
                                String msg = "";
                                try (okhttp3.Response response = client.newCall(req).execute()) {
                                    String responseBody = Objects.requireNonNull(response.body()).string();
                                    if (!response.isSuccessful()) {
                                        // ... handle failed request
                                        msg=responseBody;
                                        System.out.println("过程处理请求接口id : " + infoName + ",请求错误！错误原因"+responseBody);
                                    }
                                    // ... do something with response
                                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                    if (jsonObject != null) {
                                        Integer code = (Integer) jsonObject.get("code");
                                        if (code == 0) {
                                            executeResult = 1;
                                            System.out.println("过程处理请求接口id : " + infoName + ",请求成功！");
                                        } else {
                                            msg=responseBody;
                                            System.out.println("过程处理请求接口id : " + infoName + ",请求错误！错误原因"+responseBody);
                                        }
                                    } else {
                                        msg=responseBody;
                                        System.out.println("过程处理请求接口id : " + infoName + ",请求错误！错误原因"+responseBody);
                                    }
                                } catch (IOException e) {
                                    // ... handle IO exception
                                    msg=e.getMessage();
                                    System.out.println("过程处理请求接口id : " + infoName + ",请求错误！错误原因"+e.getMessage());
                                }
                                String porcessMessage = "";
                                if (executeResult == 1) {
                                    porcessMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                                    if (processLog) addLog(executeResult, nodeName, porcessMessage);
                                } else {
                                    porcessMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: " + msg;
                                    if (processLog) addLog(executeResult, nodeName, porcessMessage);
                                    return Response.notOk("过程处理请求接口名 : " +infoName + ",请求错误！错误原因"+msg);
                                }
                            }
                        }
                    }
                    if (aopNodeLoge != null && aopNodeLoge) {
                        String aopMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + nodeName + StringPool.RIGHT_SQ_BRACKET + "执行结束";
                        addLog(1, nodeName, aopMessage);
                    }
                }
                //开始执行接口
                for (int i = 0; i < aopExecuteArray.size(); i++) {
                    //获取到当前节点变量赋值
                    JSONArray varAssignArray = aopExecuteArray.getJSONObject(i).getJSONArray(SchemaConst.AOP_NODEVARASSIGN);
                    String nodeName = aopExecuteArray.getJSONObject(i).getString(SchemaConst.AOP_NODENAME);
                    Boolean aopNodeLoge = aopExecuteArray.getJSONObject(i).getBoolean(SchemaConst.AOP_NODELOG);
                    if (aopNodeLoge != null && aopNodeLoge) {
                        String aopMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + nodeName + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                        addLog(1, nodeName, aopMessage);
                    }
                    if (varAssignArray != null && varAssignArray.size() > 0) {
                        for (int index = 0; index < varAssignArray.size(); index++) {
                            JSONObject varObj = varAssignArray.getJSONObject(index);
                            Integer varType = varObj.getInteger(SchemaConst.VAR_TYPE);
                            String varCode = varObj.getString(SchemaConst.VAR_CODE);
                            if (aopNodeLoge != null && aopNodeLoge) {
                                String varStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                                addLog(1, nodeName, varStartMessage);
                            }
                            Integer executeResult = -1;
                            String varMessage = "";
                            // 如果是普通的值
                            if (varType == 0) {
                                varMaps.put(varObj.getString(SchemaConst.VAR_CODE), varObj.getString(SchemaConst.VAR_VALUE));
                            }
                            // 如果是参数
                            if (varType == 1) {
                                JSONArray valueArray = varObj.getJSONArray(SchemaConst.VAR_VALUE);
                                JSONObject varValue = valueArray.getJSONObject(0);
                                Integer parentId = varValue.getInteger(SchemaConst.PARENT_ID);
                                if (parentId == 0) {
                                    String inputCode = varValue.getString(SchemaConst.VARVALUE_LABEL);
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), paramMap.get(inputCode));
                                } else if (parentId == 2) {
                                    switch (varValue.getInteger(SchemaConst.VARVALUE_VALUE)) {
                                        case 0: //yyyy-MM-dd HH:mm:ss
                                            DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format0));
                                            break;
                                        case 1:// yyyy-MM-dd hh:mm:ss
                                            DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format1));
                                            break;
                                        case 2:// yyyy-MM-dd
                                            DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format2));
                                            break;
                                        case 3:// HH:mm:ss
                                            DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format3));
                                            break;
                                        case 4:// hh:mm:ss
                                            DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format4));
                                            break;
                                    }
                                }
                            }
                            // 如果变量是sql语句
                            if (varType == 2) {
                                JSONObject dbObj = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                                String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                                String field = dbObj.getString(SchemaConst.SQL_FIELD);
                                List<Entity> maps = new ArrayList<>();
                                try {
                                    maps = dbExecutor.executeQuery(dbId, replaceSqlParam(querySql, paramMap, varMaps));
                                } catch (Exception e) {
                                    if (aopNodeLoge != null && aopNodeLoge) {
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因: " + e.getMessage();
                                        addLog(executeResult, nodeName, varMessage);
                                        return Response.notOk("sql" + querySql + "执行错误,错误原因:" + e.getMessage());
                                    }
                                }
                                //只去第一条的 field字段
                                if (maps.size() > 0) {
                                    Object sqlResult = maps.get(0).get(field);
                                    //吧code  跟值  对应 存到map  后续要用
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), sqlResult);
                                }
                            }
                            // 如果是请求接口 默认套娃 再次请求此接口
                            if (varType == 3) {
                                JSONObject varValueObject = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                String infoId = varValueObject.getString(SchemaConst.INTERFACE_INFOID);
                                String infoName = this.getById(infoId).getName();
                                OkHttpClient client = new OkHttpClient();
                                //获取到当前请求的host 用于套娃请求
                                String requestURL = request.getRequestURL().toString();
                                String host = serverConfig.getLocalUrl();
                                HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                                Request.Builder url = new Request.Builder().url(builder.build());

                                //转发请求头继续塞入
                                Enumeration<String> headers = request.getHeaderNames();
                                while (headers.hasMoreElements()) {
                                    String key = headers.nextElement();
                                    url.addHeader(key, request.getHeader(key));
                                }
                                //拼接参数
                                JSONArray paramsArray = varObj.getJSONObject(SchemaConst.VAR_VALUE).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                                Map<String, String> paramsMap = new HashMap<>();
                                if (CollectionUtil.isNotEmpty(paramsArray)) {
                                    for (int idx = 0; idx < paramsArray.size(); idx++) {
                                        JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                        Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                        String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                        String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                        //如果变量配置类型为0   默认value  就是值
                                        if (type == 0) {
                                            paramsMap.put(key, value);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                            String param = paramMap.get(paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_LABEL));
                                            if (StringUtil.isNotBlank(param)) {
                                                paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                            } else {
                                                //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                                param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                                switch (param) {
                                                    case "0": //yyyy-MM-dd HH:mm:ss
                                                        DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format0));
                                                        break;
                                                    case "1":// yyyy-MM-dd hh:mm:ss
                                                        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format1));
                                                        break;
                                                    case "2":// yyyy-MM-dd
                                                        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                        paramsMap.put(key, LocalDateTime.now().format(format2));
                                                        break;
                                                    case "3":// HH:mm:ss
                                                        DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format3));
                                                        break;
                                                    case "4":// hh:mm:ss
                                                        DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format4));
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                }

                                MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                                Request req = url.post(body).build();
                                try (okhttp3.Response response = client.newCall(req).execute()) {
                                    String responseBody = Objects.requireNonNull(response.body()).string();
                                    if (!response.isSuccessful()) {
                                        // ... handle failed request
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+responseBody;
                                        if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                        return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                                    }
                                    // ... do something with response
                                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                    if (jsonObject != null) {
                                        Integer code = (Integer) jsonObject.get("code");
                                        if (code == 0) {
                                            JSONObject data = jsonObject.getJSONObject("data");
                                            JSONObject varValue = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                            String interfaceField = varValue.getString(SchemaConst.INTERFACE_FIELD);
                                            varMaps.put(varCode, data.get(interfaceField));
                                        } else {
                                            varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！" + responseBody;
                                            if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                            return Response.notOk("接口名:" +infoName + " ,请求错误！错误原因"+responseBody);
                                        }
                                    } else {
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！" + responseBody;
                                        if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                        return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                                    }
                                } catch (IOException e) {
                                    // ... handle IO exception
                                    varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+e.getMessage();
                                    if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                    return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+e.getMessage());
                                }
                            }
                            executeResult = 1;
                            varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "成功！";
                            if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                        }
                    }

                    //获取到当前节点所要执行的处理
                    JSONArray processArray = aopExecuteArray.getJSONObject(i).getJSONArray(SchemaConst.AOP_PROCESS);
                    if (processArray != null && processArray.size() > 0) {
                        for (int index = 0; index < processArray.size(); index++) {
                            JSONObject process = processArray.getJSONObject(index);
                            Integer processType = process.getInteger(SchemaConst.PROCESS_TYPE);
                            Boolean processLog = process.getBoolean(SchemaConst.PROCESS_LOG);
                            String showSetting = process.getString(SchemaConst.SHOW_SETTING);
                            if (processLog) {
                                String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                                addLog(1, nodeName, porcessStartMessage);
                            }
                            //type ==0  是执行sql
                            if (processType == 1) {
                                JSONObject dbObj = process.getJSONObject(SchemaConst.PROCESS_SETTING);
                                String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                                String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                                String field = dbObj.getString(SchemaConst.SQL_FIELD);
                                String sqlStr = replaceSqlParam(querySql, paramMap, varMaps);
                                try {
                                    String sqlTtype = sqlStr.substring(0, 6);
                                    if (StringUtil.equalsIgnoreCase(sqlTtype, "select")) {
                                        dbExecutor.executeQuery(dbId, sqlStr);
                                    } else {
                                        dbExecutor.batchExecuteNonParam(dbId, sqlStr);
                                    }
                                } catch (Exception e) {
                                    if (processLog) {
                                        String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因:" + e.getMessage();
                                        addLog(-1, nodeName, porcessStartMessage);
                                        return Response.notOk("sql" + querySql + "执行错误,错误原因:" + e.getMessage());
                                    }
                                }
                                if (processLog) {
                                    String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                                    addLog(1, nodeName, porcessStartMessage);
                                }
                            }
                            // type == 1 是请求api
                            if (processType == 0) {
                                String infoId = process.getJSONObject(SchemaConst.PROCESS_SETTING).getString(SchemaConst.INTERFACE_INFOID);
                                String infoName=this.getById(infoId).getName();
                                OkHttpClient client = new OkHttpClient();
                                //获取到当前请求的host 用于套娃请求
                                String requestURL = request.getRequestURL().toString();
                                String host = serverConfig.getLocalUrl();

                                HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                                Request.Builder url = new Request.Builder().url(builder.build());

                                //转发请求头继续塞入
                                Enumeration<String> headers = request.getHeaderNames();
                                while (headers.hasMoreElements()) {
                                    String key = headers.nextElement();
                                    url.addHeader(key, request.getHeader(key));
                                }
                                //拼接参数
                                JSONArray paramsArray = process.getJSONObject(SchemaConst.PROCESS_SETTING).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                                Map<String, String> paramsMap = new HashMap<>();
                                if (CollectionUtil.isNotEmpty(paramsArray)) {
                                    for (int idx = 0; idx < paramsArray.size(); idx++) {
                                        JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                        Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                        String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                        String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                        //如果变量配置类型为0   默认value  就是值
                                        if (type == 0) {
                                            paramsMap.put(key, value);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                            String param = paramMap.get(paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_LABEL));
                                            if (StringUtil.isNotBlank(param)) {
                                                paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                            } else {
                                                //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                                param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                                switch (param) {
                                                    case "0": //yyyy-MM-dd HH:mm:ss
                                                        DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format0));
                                                        break;
                                                    case "1":// yyyy-MM-dd hh:mm:ss
                                                        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format1));
                                                        break;
                                                    case "2":// yyyy-MM-dd
                                                        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                        paramsMap.put(key, LocalDateTime.now().format(format2));
                                                        break;
                                                    case "3":// HH:mm:ss
                                                        DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format3));
                                                        break;
                                                    case "4":// hh:mm:ss
                                                        DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format4));
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                }

                                MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                                Request req = url.post(body).build();
                                Integer executeResult = -1;
                                String msg = "";
                                try (okhttp3.Response response = client.newCall(req).execute()) {
                                    if (!response.isSuccessful()) {
                                        // ... handle failed request
                                        System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                    }

                                    // ... do something with response
                                    String responseBody = Objects.requireNonNull(response.body()).string();
                                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                    msg =responseBody;
                                    if (jsonObject != null) {
                                        Integer code = (Integer) jsonObject.get("code");
                                        if (code == 0) {
                                            executeResult = 1;
                                            System.out.println("过程处理请求接口id : " + infoName + ",请求成功！");
                                        } else {
                                            System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                        }
                                    }
                                    System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");


                                } catch (IOException e) {
                                    // ... handle IO exception
                                    msg=e.getMessage();
                                    System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                }
                                String porcessMessage = "";
                                if (executeResult == 1) {
                                    porcessMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                                    if (processLog) addLog(executeResult, nodeName, porcessMessage);
                                } else {
                                    porcessMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: " + msg;
                                    if (processLog) addLog(executeResult, nodeName, porcessMessage);
                                    return Response.notOk("过程处理请求接口名 : " +infoName + ",请求错误！错误原因"+msg);
                                }
                            }
                        }
                    }
                    if (aopNodeLoge != null && aopNodeLoge) {
                        String aopMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + nodeName + StringPool.RIGHT_SQ_BRACKET + "执行结束";
                        addLog(1, nodeName, aopMessage);
                    }
                }

                //接口执行结束
                for (int i = 0; i < aopEndArray.size(); i++) {
                    //获取到当前节点变量赋值
                    JSONArray varAssignArray = aopEndArray.getJSONObject(i).getJSONArray(SchemaConst.AOP_NODEVARASSIGN);
                    String nodeName = aopEndArray.getJSONObject(i).getString(SchemaConst.AOP_NODENAME);
                    Boolean aopNodeLoge = aopEndArray.getJSONObject(i).getBoolean(SchemaConst.AOP_NODELOG);
                    if (aopNodeLoge != null && aopNodeLoge) {
                        String aopMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + nodeName + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                        addLog(1, nodeName, aopMessage);
                    }
                    if (varAssignArray != null && varAssignArray.size() > 0) {
                        for (int index = 0; index < varAssignArray.size(); index++) {
                            JSONObject varObj = varAssignArray.getJSONObject(index);
                            Integer varType = varObj.getInteger(SchemaConst.VAR_TYPE);
                            String varCode = varObj.getString(SchemaConst.VAR_CODE);
                            if (aopNodeLoge != null && aopNodeLoge) {
                                String varStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                                addLog(1, nodeName, varStartMessage);
                            }
                            Integer executeResult = -1;
                            String varMessage = "";
                            // 如果是普通的值
                            if (varType == 0) {
                                varMaps.put(varObj.getString(SchemaConst.VAR_CODE), varObj.getString(SchemaConst.VAR_VALUE));
                            }
                            // 如果是参数
                            if (varType == 1) {
                                JSONArray varValueArray = varObj.getJSONArray(SchemaConst.VAR_VALUE);
                                JSONObject varValue = varValueArray.getJSONObject(0);
                                Integer parentId = varValue.getInteger(SchemaConst.PARENT_ID);
                                //根据配置的参数code  如果code 能从参数里面知道相应的key  就使用的是参数值 如果找不到 则是 使用系统时间的值
                                if (parentId == 0) {
                                    String inputCode = varValue.getString(SchemaConst.VARVALUE_LABEL);
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), paramMap.get(inputCode));
                                } else {
                                    switch (varValue.getInteger(SchemaConst.VARVALUE_VALUE)) {
                                        case 0: //yyyy-MM-dd HH:mm:ss
                                            DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format0));
                                            break;
                                        case 1:// yyyy-MM-dd hh:mm:ss
                                            DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format1));
                                            break;
                                        case 2:// yyyy-MM-dd
                                            DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format2));
                                            break;
                                        case 3:// HH:mm:ss
                                            DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format3));
                                            break;
                                        case 4:// hh:mm:ss
                                            DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                            varMaps.put(varObj.getString(SchemaConst.VAR_CODE), LocalDateTime.now().format(format4));
                                            break;
                                    }
                                }
                            }
                            // 如果变量是sql语句
                            if (varType == 2) {
                                JSONObject dbObj = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                                String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                                String field = dbObj.getString(SchemaConst.SQL_FIELD);
                                List<Entity> maps = new ArrayList<>();
                                try {
                                    maps = dbExecutor.executeQuery(dbId, replaceSqlParam(querySql, paramMap, varMaps));
                                } catch (Exception e) {
                                    if (aopNodeLoge != null && aopNodeLoge) {
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因: " + e.getMessage();
                                        addLog(executeResult, nodeName, varMessage);
                                        return Response.notOk("sql" + querySql + "执行错误,错误原因:" + e.getMessage());
                                    }
                                }
                                //只去第一条的 field字段
                                if (maps.size() > 0) {
                                    Object sqlResult = maps.get(0).get(field);
                                    //吧code  跟值  对应 存到map  后续要用
                                    varMaps.put(varObj.getString(SchemaConst.VAR_CODE), sqlResult);
                                }
                            }
                            // 如果是请求接口 默认套娃 再次请求此接口
                            if (varType == 3) {
                                JSONObject varValueObject = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                String infoId = varValueObject.getString(SchemaConst.INTERFACE_INFOID);
                                String infoName = this.getById(infoId).getName();
                                OkHttpClient client = new OkHttpClient();
                                //获取到当前请求的host 用于套娃请求
                                String requestURL = request.getRequestURL().toString();
                                String host = serverConfig.getLocalUrl();

                                HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                                Request.Builder url = new Request.Builder().url(builder.build());

                                //转发请求头继续塞入
                                Enumeration<String> headers = request.getHeaderNames();
                                while (headers.hasMoreElements()) {
                                    String key = headers.nextElement();
                                    url.addHeader(key, request.getHeader(key));
                                }
                                //拼接参数
                                JSONArray paramsArray = varObj.getJSONObject(SchemaConst.VAR_VALUE).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                                Map<String, String> paramsMap = new HashMap<>();
                                if (CollectionUtil.isNotEmpty(paramsArray)) {
                                    for (int idx = 0; idx < paramsArray.size(); idx++) {
                                        JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                        Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                        String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                        String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                        //如果变量配置类型为0   默认value  就是值
                                        if (type == 0) {
                                            paramsMap.put(key, value);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                            String param = paramMap.get(value);
                                            if (StringUtil.isNotBlank(param)) {
                                                paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                            } else {
                                                //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                                param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                                switch (param) {
                                                    case "0": //yyyy-MM-dd HH:mm:ss
                                                        DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format0));
                                                        break;
                                                    case "1":// yyyy-MM-dd hh:mm:ss
                                                        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format1));
                                                        break;
                                                    case "2":// yyyy-MM-dd
                                                        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                        paramsMap.put(key, LocalDateTime.now().format(format2));
                                                        break;
                                                    case "3":// HH:mm:ss
                                                        DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format3));
                                                        break;
                                                    case "4":// hh:mm:ss
                                                        DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format4));
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                }
                                MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                                Request req = url.post(body).build();

                                try (okhttp3.Response response = client.newCall(req).execute()) {
                                    String responseBody = Objects.requireNonNull(response.body()).string();
                                    if (!response.isSuccessful()) {
                                        // ... handle failed request
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+responseBody;
                                        if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                        return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                                    }

                                    // ... do something with response
                                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                    if (jsonObject != null) {
                                        Integer code = (Integer) jsonObject.get("code");
                                        if (code == 0) {
                                            JSONObject data = jsonObject.getJSONObject("data");
                                            JSONObject varValue = varObj.getJSONObject(SchemaConst.VAR_VALUE);
                                            String interfaceField = varValue.getString(SchemaConst.INTERFACE_FIELD);
                                            varMaps.put(varCode, data.get(interfaceField));
                                        } else {
                                            varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！" + responseBody;
                                            if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                            return Response.notOk("接口id:" + info.getName() + " ,请求错误！错误原因"+responseBody);
                                        }
                                    } else {
                                        varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+responseBody;
                                        if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                        return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                                    }
                                } catch (IOException e) {
                                    // ... handle IO exception
                                    varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "失败,原因:接口id: " + infoId + " ,请求错误！"+e.getMessage();
                                    if (aopNodeLoge) addLog(executeResult, nodeName, varMessage);
                                    return Response.notOk("接口名:" +infoName+  " ,请求错误！错误原因"+e.getMessage());
                                }
                            }
                            varMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "变量赋值:" + varCode + StringPool.RIGHT_SQ_BRACKET + "成功";
                            if (aopNodeLoge) addLog(1, info.getName(), varMessage);
                        }
                    }
                    //获取到当前节点所要执行的处理
                    JSONArray processArray = aopEndArray.getJSONObject(i).getJSONArray(SchemaConst.AOP_PROCESS);
                    if (processArray != null && processArray.size() > 0) {
                        for (int index = 0; index < processArray.size(); index++) {
                            JSONObject process = processArray.getJSONObject(index);
                            Integer processType = process.getInteger(SchemaConst.PROCESS_TYPE);
                            Boolean processLog = process.getBoolean(SchemaConst.PROCESS_LOG);
                            String showSetting = process.getString(SchemaConst.SHOW_SETTING);
                            if (processLog) {
                                String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "开始执行";
                                addLog(1, nodeName, porcessStartMessage);
                            }
                            //type ==0  是执行sql
                            if (processType == 1) {

                                JSONObject dbObj = process.getJSONObject(SchemaConst.PROCESS_SETTING);
                                String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                                String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                                String field = dbObj.getString(SchemaConst.SQL_FIELD);
                                String sqlStr = replaceSqlParam(querySql, paramMap, varMaps);
                                try {
                                    String sqlTtype = sqlStr.substring(0, 6);
                                    if (StringUtil.equalsIgnoreCase(sqlTtype, "select")) {
                                        dbExecutor.executeQuery(dbId, sqlStr);
                                    } else {
                                        dbExecutor.batchExecuteNonParam(dbId, sqlStr);
                                    }
                                } catch (Exception e) {
                                    if (processLog) {
                                        String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因:" + e.getMessage();
                                        addLog(-1, nodeName, porcessStartMessage);
                                        return Response.notOk("sql" + querySql + "执行错误,错误原因:" + e.getMessage());
                                    }
                                }
                                if (processLog) {
                                    String porcessStartMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                                    addLog(1, nodeName, porcessStartMessage);
                                }
                            }
                            // type == 1 是请求api
                            if (processType == 0) {
                                String infoId = process.getString(SchemaConst.INTERFACE_INFOID);
                                String infoName=this.getById(infoId).getName();
                                OkHttpClient client = new OkHttpClient();

                                //获取到当前请求的host 用于套娃请求
                                String requestURL = request.getRequestURL().toString();
                                String host = serverConfig.getLocalUrl();

                                HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(host + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                                Request.Builder url = new Request.Builder().url(builder.build());

                                //转发请求头继续塞入
                                Enumeration<String> headers = request.getHeaderNames();
                                while (headers.hasMoreElements()) {
                                    String key = headers.nextElement();
                                    url.addHeader(key, request.getHeader(key));
                                }
                                //拼接参数
                                JSONArray paramsArray = process.getJSONObject(SchemaConst.PROCESS_SETTING).getJSONArray(SchemaConst.INTERFACE_PARAMS);
                                Map<String, String> paramsMap = new HashMap<>();
                                if (CollectionUtil.isNotEmpty(paramsArray)) {
                                    for (int idx = 0; idx < paramsArray.size(); idx++) {
                                        JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                        Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                        String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                        String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                        Integer executeResult = -1;
                                        String varMessage = "";
                                        //如果变量配置类型为0   默认value  就是值
                                        if (type == 0) {
                                            paramsMap.put(key, value);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                            String param = paramMap.get(value);
                                            if (StringUtil.isNotBlank(param)) {
                                                paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                            } else {
                                                //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                                param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                                switch (param) {
                                                    case "0": //yyyy-MM-dd HH:mm:ss
                                                        DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format0));
                                                        break;
                                                    case "1":// yyyy-MM-dd hh:mm:ss
                                                        DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format1));
                                                        break;
                                                    case "2":// yyyy-MM-dd
                                                        DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                        paramsMap.put(key, LocalDateTime.now().format(format2));
                                                        break;
                                                    case "3":// HH:mm:ss
                                                        DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format3));
                                                        break;
                                                    case "4":// hh:mm:ss
                                                        DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                        paramsMap.put(key, LocalDateTime.now().format(format4));
                                                        break;
                                                }
                                            }
                                        }
                                    }
                                }

                                MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                                okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                                Request req = url.post(body).build();
                                Integer executeResult = -1;
                                String msg = "";
                                try (okhttp3.Response response = client.newCall(req).execute()) {
                                    String responseBody = Objects.requireNonNull(response.body()).string();
                                    msg=responseBody;
                                    if (!response.isSuccessful()) {
                                        // ... handle failed request
                                        System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                    }
                                    // ... do something with response
                                    JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                    if (jsonObject != null) {
                                        Integer code = (Integer) jsonObject.get("code");
                                        if (code == 0) {
                                            executeResult = 1;
                                            System.out.println("过程处理请求接口id : " + infoName + ",请求成功！");
                                        } else {
                                            System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                        }
                                    }
                                    System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                } catch (IOException e) {
                                    // ... handle IO exception
                                    msg=e.getMessage();
                                    System.out.println("过程处理请求接口id : " + infoName + ",请求错误！");
                                }
                                String porcessMessage = "";
                                if (executeResult == 1) {
                                    porcessMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                                    if (processLog) addLog(executeResult, nodeName, porcessMessage);
                                } else {
                                    porcessMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + "过程处理:" + showSetting + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: " + msg;
                                    if (processLog) addLog(executeResult, nodeName, porcessMessage);
                                    return Response.notOk("过程处理请求接口名 : " +infoName + ",请求错误！错误原因"+msg);
                                }
                            }
                        }
                    }
                    if (aopNodeLoge != null && aopNodeLoge) {
                        String aopMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + StringPool.LEFT_SQ_BRACKET + nodeName + StringPool.RIGHT_SQ_BRACKET + "执行结束";
                        addLog(1, nodeName, aopMessage);
                    }
                }


                Map<String, Object> resultMap = new HashMap<>();
                for (int i = 0; i < outputArray.size(); i++) {
                    JSONObject output = outputArray.getJSONObject(i);
                    Integer outputSource = output.getInteger(SchemaConst.OUTPUT_SOURCE);

                    // outputSource == 0  以入参 作为 出参 输出  如果有设置参数编码 默认以编码作为key  如果没有 入参key 是什么 出参key就是什么
                    if (outputSource == 0) {
                        resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), paramMap.get(output.getString(SchemaConst.OUTPUT_CODE)));
                    }


                    // outputSource == 1  以接口变量作为出参
                    if (outputSource == 1) {
                        Object varObject = varMaps.get(output.getString(SchemaConst.OUTPUT_CODE));
                        resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), varObject);
                    }

                    //outputSource == 2 是自定义出参  需要执行 sql  或者 执行接口
                    if (outputSource == 2) {
                        //自定义出参的类型
                        Integer outputType = output.getInteger(SchemaConst.OUTPUT_TYPE);
                        // outputType == 0  以值作为出参
                        if (outputType == 0) {
                            resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), output.getString(SchemaConst.OUTPUT_VALUE));
                        }

                        // outputSource == 1  以入参 作为 出参 输出  如果有设置参数编码 默认以编码作为key  如果没有 入参key 是什么 出参key就是什么
                        if (outputType == 1) {
                            //以参数作为 出参  有三种可能
                            JSONArray outValueArray = output.getJSONArray(SchemaConst.OUTPUT_VALUE);
                            if (outValueArray != null && outValueArray.size() > 0) {
                                JSONObject outValueObj = outValueArray.getJSONObject(0);
                                Integer paramType = outValueObj.getInteger(SchemaConst.PARENT_ID);
                                String key = outValueObj.getString(SchemaConst.VARVALUE_LABEL);

                                if (paramType == 0) {//以入参

                                    resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), paramMap.get(key));
                                }
                                if (paramType == 1) { //以变量
                                    resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), varMaps.get(key));
                                }
                                if (paramType == 2) { //以变量
                                    String param = outValueObj.getString(SchemaConst.VARVALUE_VALUE);
                                    switch (param) {
                                        case "0": //yyyy-MM-dd HH:mm:ss
                                            DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                            resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), LocalDateTime.now().format(format0));
                                            break;
                                        case "1":// yyyy-MM-dd hh:mm:ss
                                            DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                            resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), LocalDateTime.now().format(format1));
                                            break;
                                        case "2":// yyyy-MM-dd
                                            DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                            resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), LocalDateTime.now().format(format2));
                                            break;
                                        case "3":// HH:mm:ss
                                            DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                            resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), LocalDateTime.now().format(format3));
                                            break;
                                        case "4":// hh:mm:ss
                                            DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                            resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), LocalDateTime.now().format(format4));
                                            break;
                                    }
                                }

                            } else {
                                resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), null);
                            }
                        }


                        // outputType == 2  sql语句
                        if (outputType == 2) {
                            JSONObject dbObj = output.getJSONObject(SchemaConst.OUTPUT_VALUE);

                            String dbId = dbObj.getString(SchemaConst.SQL_DBID);
                            String querySql = dbObj.getString(SchemaConst.SQL_STRING);
                            String field = dbObj.getString(SchemaConst.SQL_FIELD);
                            List<Entity> maps = dbExecutor.executeQuery(dbId, replaceSqlParam(querySql, paramMap, varMaps));
                            //只去第一条的 field字段
                            if (maps.size() > 0) {

                                Integer valType = output.getInteger(SchemaConst.OUTPUT_VALTYPE);
                                //如果是字符
                                if (valType == 0) {
                                    Object sqlResult = maps.get(0).get(field);
                                    //吧code  跟值  对应 存到map  后续要用
                                    resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), sqlResult);
                                } else { //如果是列表
                                    JSONObject jsonObject = output.getJSONObject(SchemaConst.OUTPUT_SAVECODE);
                                    JSONArray listConfigArray = jsonObject.getJSONArray(SchemaConst.OUTPUT_OBJVARIABLE);

                                    List<String> fieldList = new ArrayList<>();
                                    for (int index = 0; index < listConfigArray.size(); index++) {
                                        fieldList.add(listConfigArray.getJSONObject(index).getString(SchemaConst.OUTPUT_OBJNAME));
                                    }

                                    List<Map<String, Object>> resultList = new ArrayList<>();

                                    for (int idx = 0; idx < maps.size(); idx++) {
                                        Map<String, Object> stringObjectMap = maps.get(idx);
                                        stringObjectMap.keySet().retainAll(fieldList);
                                        resultList.add(stringObjectMap);
                                    }

                                    resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), resultList);
                                }
                            } else {
                                resultMap.put(output.getString(SchemaConst.OUTPUT_CODE), new ArrayList<>());
                            }
                        }

                        // 如果是请求接口 默认套娃 再次请求此接口
                        if (outputType == 3) {
                            JSONObject outputObj = output.getJSONObject(SchemaConst.OUTPUT_VALUE);

                            String infoId = outputObj.getString(SchemaConst.INTERFACE_INFOID);

                            String infoName = this.getById(infoId).getName();

                            OkHttpClient client = new OkHttpClient();

                            //获取到当前请求的host 用于套娃请求

                            HttpUrl.Builder builder = Objects.requireNonNull(HttpUrl.parse(serverConfig.getLocalUrl() + "/xjr-interface-info/execute/" + infoId)).newBuilder();

                            Request.Builder url = new Request.Builder().url(builder.build());

                            //转发请求头继续塞入
                            Enumeration<String> headers = request.getHeaderNames();
                            while (headers.hasMoreElements()) {
                                String key = headers.nextElement();
                                url.addHeader(key, request.getHeader(key));
                            }
                            //拼接参数
                            JSONArray paramsArray = outputObj.getJSONArray(SchemaConst.INTERFACE_PARAMS);
                            Map<String, String> paramsMap = new HashMap<>();
                            if (CollectionUtil.isNotEmpty(paramsArray)) {
                                for (int idx = 0; idx < paramsArray.size(); idx++) {
                                    JSONObject paramsObj = paramsArray.getJSONObject(idx);
                                    Integer type = paramsObj.getInteger(SchemaConst.PARAM_VAL_TYPE);
                                    String key = paramsObj.getString(SchemaConst.PARAM_NAME);
                                    String value = paramsObj.getString(SchemaConst.PARAM_VALUE);
                                    //如果变量配置类型为0   默认value  就是值
                                    if (type == 0) {
                                        paramsMap.put(key, value);
                                    } else {
                                        //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果有值 就代表使用入参作为参数
                                        String param = paramMap.get(paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_LABEL));
                                        if (StringUtil.isNotBlank(param)) {
                                            paramsMap.put(paramsObj.getString(SchemaConst.PARAM_NAME), param);
                                        } else {
                                            //如果变量配置类型为1  使用value 作为key  从body里面取参数 如果无值 就代表使用时间作为入参
                                            param = paramsObj.getJSONArray(SchemaConst.PARAM_VALUE).getJSONObject(0).getString(SchemaConst.VARVALUE_VALUE);
                                            switch (param) {
                                                case "0": //yyyy-MM-dd HH:mm:ss
                                                    DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                                                    paramsMap.put(key, LocalDateTime.now().format(format0));
                                                    break;
                                                case "1":// yyyy-MM-dd hh:mm:ss
                                                    DateTimeFormatter format1 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                                                    paramsMap.put(key, LocalDateTime.now().format(format1));
                                                    break;
                                                case "2":// yyyy-MM-dd
                                                    DateTimeFormatter format2 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                                                    paramsMap.put(key, LocalDateTime.now().format(format2));
                                                    break;
                                                case "3":// HH:mm:ss
                                                    DateTimeFormatter format3 = DateTimeFormatter.ofPattern("HH:mm:ss");
                                                    paramsMap.put(key, LocalDateTime.now().format(format3));
                                                    break;
                                                case "4":// hh:mm:ss
                                                    DateTimeFormatter format4 = DateTimeFormatter.ofPattern("hh:mm:ss");
                                                    paramsMap.put(key, LocalDateTime.now().format(format4));
                                                    break;
                                            }
                                        }
                                    }
                                }
                            }

                            MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
                            okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
                            Request req = url.post(body).build();
                            try (okhttp3.Response response = client.newCall(req).execute()) {
                                String responseBody = Objects.requireNonNull(response.body()).string();
                                if (!response.isSuccessful()) {
                                    // ... handle failed request
                                    return Response.notOk("接口名:" +infoName+ " ,请求错误！错误原因"+responseBody);
                                }

                                // ... do something with response
                                JSONObject jsonObject = JSONObject.parseObject(responseBody);
                                if (jsonObject != null) {
                                    Integer code = (Integer) jsonObject.get("code");
                                    if (code == 0) {
                                        JSONObject data = jsonObject.getJSONObject("data");
                                        String varCode = output.getString(SchemaConst.OUTPUT_CODE);
                                        String interfaceField = outputObj.getString(SchemaConst.INTERFACE_FIELD);
                                        varMaps.put(varCode, data.get(interfaceField));
                                        resultMap.put(varCode, data.get(interfaceField));
                                    } else {
                                        return Response.notOk("接口名:" + infoName + " ,请求错误！错误原因"+responseBody);
                                    }
                                } else {
                                    return Response.notOk("接口名:" +infoName + " ,请求错误！错误原因"+responseBody);
                                }
                            } catch (IOException e) {
                                // ... handle IO exception
                                return Response.notOk("接口名:" +infoName + " ,请求错误！错误原因"+e.getMessage());
                            }
                        }
                    }
                }
                //
                String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行结束";
                addLog(1, info.getName(), endMessage);
                Set<Map.Entry<String, Object>> entries = resultMap.entrySet();
                for (Map.Entry<String, Object> entry : entries) {
                    Object value = entry.getValue();
                    String reg4 = "^[0-9]+(.[0-9]+)?$";
                    String valueStr= String.valueOf(value);
                    if(Pattern.matches(reg4, valueStr)){
                        //为数字格式
                        entry.setValue(Integer.valueOf(valueStr));
                    }
                }
                return Response.ok(resultMap);

            }
            return Response.notOk("当前接口请求错误！");
        } else {
            return Response.notOk("没有当前接口！");
        }
    }


    /**
     * @Author: tzx
     * @Description: 执行根据接口管理配置 执行get请求
     * @Date: 2022-01-24 15:21
     */
    @Override
    public Response executeGet(XjrInterfaceInfo info, List<XjrInterfaceParams> paramsList, List<XjrInterfaceOutput> outputList, Map<String, String> paramMap, HttpServletRequest request) {
        OkHttpClient client = new OkHttpClient();
        String host = "";
        boolean isInternal = true; // 是否为内部接口
        // isinternal == 0  就是内部接口  内部接口 默认拼接当前请求的 ip:port
        if (info.getIsInternal() == 0) {
            //获取到当前请求的host 用于套娃请求
            host = serverConfig.getLocalUrl();
        } else {
            isInternal = false;
        }

        HttpUrl parse = HttpUrl.parse(host + info.getUrlAddress());
        if (parse == null) {
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: 当前接口请求地址:" + host + info.getUrlAddress() + "错误！";
            addLog(1, info.getName(), endMessage);
            return Response.notOk("当前接口请求地址:" + host + info.getUrlAddress() + "错误！");
        }
        HttpUrl.Builder builder = Objects.requireNonNull(parse).newBuilder();
        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            String value = paramMap.get(xjrInterfaceParams.getParamKey());

            //get请求没有body  如果参数设置为body  也是改为querystring
            if (xjrInterfaceParams.getType() == 1 || xjrInterfaceParams.getType() == 2) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }
            }

        }

        Request.Builder url = new Request.Builder().url(builder.build());
        //内部接口才需要使用原有hearder
        if (isInternal) {
            Enumeration<String> headers = request.getHeaderNames();
            while (headers.hasMoreElements()) {
                String key = headers.nextElement();
                url.addHeader(key, request.getHeader(key));
            }
        }

        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            String value = paramMap.get(xjrInterfaceParams.getParamKey());
            //如果有header参数
            if (xjrInterfaceParams.getType() == 0) {
                String paramKey = xjrInterfaceParams.getParamKey();
                String paramValue = xjrInterfaceParams.getParamValue();
                String headerValue = request.getHeader(paramKey);
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    url.addHeader(paramKey, value);
                } else if(StringUtil.isNotBlank(headerValue)) {
                    url.addHeader(paramKey, headerValue);
                }else {
                    url.addHeader(paramKey,paramValue);
                    }
                }
            }
        Request req = url.build();
        try (okhttp3.Response response = client.newCall(req).execute()) {
            String responseBody = Objects.requireNonNull(response.body()).string();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            if (!response.isSuccessful()) {
                // ... handle failed request
                String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: " + responseBody;
                addLog(-1, info.getName(), endMessage);
                return Response.notOk("当前接口请求错误！错误原因:"+responseBody);
            }
//            else if (jsonObject != null) {
//                Integer code = (Integer) jsonObject.get("code");
//                if (code != 0) {
//                    return Response.notOk("接口id:" + info.getName() + " ,请求错误！错误原因:"+responseBody);
//                }
//            } else {
//                return Response.notOk("接口id:" + info.getName() + " ,请求错误！错误原因:"+responseBody);
//            }
            // ... do something with response
            if (jsonObject != null) {
                //如果是内部接口  则是默认的返回格式  直接取data里面的数据
                if (isInternal) {
                    Integer code = (Integer) jsonObject.get("code");
                    if (code == 0) {
                        Map<String, Object> resultMap = new HashMap<>();
                        //如果没有配置返回值  默认使用data
                        if (outputList.size() == 0) {
                            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                            addLog(1, info.getName(), endMessage);
                            return Response.ok(jsonObject.get("data"));
                        }
                        JSONObject data = jsonObject.getJSONObject("data");
                        for (XjrInterfaceOutput output : outputList) {
                            resultMap.put(output.getOutputKey(), data.get(output.getOutputKey()));
                        }
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                        addLog(1, info.getName(), endMessage);
                        return Response.ok(resultMap);
                    } else {
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+ responseBody;
                        addLog(-1, info.getName(), endMessage);
                        return Response.notOk(code, "当前接口请求错误,错误原因:"+ responseBody);
                    }
                } else { //如果是外部接口
                    Map<String, Object> resultMap = new HashMap<>();
                    for (XjrInterfaceOutput output : outputList) {
                        String resultKey = output.getResultKey();
                        String[] keyArray = resultKey.split("\\.");

                        //如果多级
                        if (keyArray.length > 1) {
                            JSONObject data = null;

                            for (int i = 0; i < keyArray.length; i++) {
                                //第一次从 jsonobject取
                                if (i == 0) {
                                    data = jsonObject.getJSONObject(keyArray[i]);
                                }
                                // 如果是最后一级 默认使用 get()  不能使用 getJsonobject
                                else if (i == keyArray.length - 1) {
                                    if (data != null) {
                                        resultMap.put(output.getOutputKey(), data.get(keyArray[i]));
                                    }
                                }
                                //不是最后一级  使用getjsonobject
                                else {
                                    data = data.getJSONObject(keyArray[i]);
                                }

                            }

                        }
                        //如果只有一级
                        else {
                            resultMap.put(output.getOutputKey(), jsonObject.get(resultKey));
                        }
                    }
                    String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                    addLog(1, info.getName(), endMessage);
                    Set<Map.Entry<String, Object>> entries = resultMap.entrySet();
                    for (Map.Entry<String, Object> entry : entries) {
                        Object value = entry.getValue();
                        String reg4 = "^[0-9]+(.[0-9]+)?$";
                        String valueStr= String.valueOf(value);
                        if(Pattern.matches(reg4, valueStr)){
                            //为数字格式
                            entry.setValue(Integer.valueOf(valueStr));
                        }
                    }
                    return Response.ok(resultMap);
                }
            }
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败";
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因:"+responseBody);
        } catch (IOException e) {
            // ... handle IO exception
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败,失败原因:"+e.getMessage();
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因:"+e.getMessage());
        }
    }

    /**
     * @Author: tzx
     * @Description: 执行根据接口管理配置 执行post请求
     * @Date: 2022-01-24 15:33
     */
    @Override
    public Response executePost(XjrInterfaceInfo info, List<XjrInterfaceParams> paramsList, List<XjrInterfaceOutput> outputList, Map<String, String> paramMap, HttpServletRequest request) {
        MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
        OkHttpClient client = new OkHttpClient();

        String host = "";
        boolean isInternal = true; // 是否为内部接口
        // isinternal == 0 就是内部接口  内部接口 默认拼接当前请求的 ip:port
        if (info.getIsInternal() == 0) {
            //获取到当前请求的host 用于套娃请求
            host = serverConfig.getLocalUrl();
        } else {
            isInternal = false;
        }

        HttpUrl parse = HttpUrl.parse(host + info.getUrlAddress());
        if (parse == null) {
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: 当前接口请求地址:" + host + info.getUrlAddress() + "错误！";
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求地址:" + host + info.getUrlAddress() + "错误！");
        }
        HttpUrl.Builder builder = Objects.requireNonNull(parse).newBuilder();

        Map<String, String> paramsMap = new HashMap<>();

        //拼接querystring 和 body 从参数
        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            //从传入参数获取值
            String value = paramMap.get(xjrInterfaceParams.getParamKey());

            //get请求没有body  如果参数设置为body  也是改为querystring
            if (xjrInterfaceParams.getType() == 1) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    paramsMap.put(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    paramsMap.put(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }

            } else if (xjrInterfaceParams.getType() == 2) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }
            }
        }

        Request.Builder url = new Request.Builder().url(builder.build());
        //内部接口才需要使用原有hearder
        if (isInternal) {
            Enumeration<String> headers = request.getHeaderNames();
            while (headers.hasMoreElements()) {
                String key = headers.nextElement();
                url.addHeader(key, request.getHeader(key));
            }
        }

        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            String value = paramMap.get(xjrInterfaceParams.getParamKey());
            //如果有header参数
            if (xjrInterfaceParams.getType() == 0) {
                String paramKey = xjrInterfaceParams.getParamKey();
                String paramValue = xjrInterfaceParams.getParamValue();
                String headerValue = request.getHeader(paramKey);
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    url.addHeader(paramKey, value);
                } else if(StringUtil.isNotBlank(headerValue)) {
                    url.addHeader(paramKey, headerValue);
                }else {  //如果没有传入参数 则用默认参数
                    url.addHeader(paramKey,paramValue);
                }
            }
        }


        okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
        Request req = url.post(body).build();

        try (okhttp3.Response response = client.newCall(req).execute()) {
            String responseBody = Objects.requireNonNull(response.body()).string();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            if (!response.isSuccessful()) {
                // ... handle failed request
                String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+responseBody;
                addLog(-1, info.getName(), endMessage);
                return Response.notOk("当前接口请求错误,错误原因: "+responseBody);
            }

            // ... do something with response
            if (jsonObject != null) {
                //如果是内部接口  则是默认的返回格式  直接取data里面的数据
                if (isInternal) {
                    Integer code = (Integer) jsonObject.get("code");
                    if (code == 0) {
                        Map<String, Object> resultMap = new HashMap<>();

                        //如果没有配置返回值  默认使用data
                        if (outputList.size() == 0) {
                            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                            addLog(1, info.getName(), endMessage);
                            return Response.ok(jsonObject.get("data"));
                        }
                        JSONObject data = jsonObject.getJSONObject("data");
                        for (XjrInterfaceOutput output : outputList) {
                            resultMap.put(output.getOutputKey(), data.get(output.getOutputKey()));
                        }
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                        addLog(1, info.getName(), endMessage);
                        return Response.ok(resultMap);
                    } else {
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+responseBody;
                        addLog(-1, info.getName(), endMessage);
                        return Response.notOk(code, "当前接口请求错误,错误原因: "+responseBody);
                    }
                } else { //如果是外部接口
                    Map<String, Object> resultMap = new HashMap<>();
                    for (XjrInterfaceOutput output : outputList) {
                        String resultKey = output.getResultKey();
                        String[] keyArray = resultKey.split(StringPool.BACK_SLASH + StringPool.DOT);

                        //如果多级
                        if (keyArray.length > 0) {
                            JSONObject data = jsonObject;
                            for (int i = 0; i < keyArray.length; i++) {
                                // 如果是最后一级 默认使用 get()  不能使用 getJsonobject
                                if (i == keyArray.length - 1) {
                                    resultMap.put(output.getOutputKey(), data.get(keyArray[i]));
                                    break;
                                } else {
                                    //不是最后一级  使用getjsonobject
                                    data = data.getJSONObject(keyArray[i]);
                                }
                            }
                        }
                    }
                    String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                    addLog(1, info.getName(), endMessage);
                    Set<Map.Entry<String, Object>> entries = resultMap.entrySet();
                    for (Map.Entry<String, Object> entry : entries) {
                        Object value = entry.getValue();
                        String reg4 = "^[0-9]+(.[0-9]+)?$";
                        String valueStr= String.valueOf(value);
                        if(Pattern.matches(reg4, valueStr)){
                            //为数字格式
                            entry.setValue(Integer.valueOf(valueStr));
                        }
                    }
                    return Response.ok(resultMap);
                }
            }
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败,失败原因: "+responseBody;
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因: "+responseBody);


        } catch (IOException e) {
            // ... handle IO exception
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败,失败原因:" + e.getMessage();
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因: "+e.getMessage());
        }
    }

    @Override
    @Transactional
    public Boolean add(AddInfoDto dto) {
        int count = this.count(Wrappers.<XjrInterfaceInfo>query().lambda().eq(XjrInterfaceInfo::getName, dto.getName()));

        if (count > 0) {
            throw new RuntimeException("已存在相同名称的接口！");
        }
        XjrInterfaceInfo info = BeanUtil.copy(dto, XjrInterfaceInfo.class);

        boolean success = this.save(info);
        if (success) {
            //如果不是自定义接口
            List<AddParamDto> params = Optional.ofNullable(dto.getParams()).orElse(new ArrayList<>());
            List<AddOutputDto> outputs = Optional.ofNullable(dto.getOutputs()).orElse(new ArrayList<>());


            if (params.size() > 0) {
                List<XjrInterfaceParams> paramsList = BeanUtil.copyList(params, XjrInterfaceParams.class);
                for (XjrInterfaceParams param : paramsList) {
                    param.setInfoId(info.getId());
                }
                paramsService.saveBatch(paramsList);
            }

            if (outputs.size() > 0) {
                List<XjrInterfaceOutput> outputList = BeanUtil.copyList(outputs, XjrInterfaceOutput.class);
                for (XjrInterfaceOutput output : outputList) {
                    output.setInfoId(info.getId());
                }
                outputService.saveBatch(outputList);
            }
            return true;

        } else {
            throw new RuntimeException("新增接口管理错误！");
        }
    }

    public boolean saveBatch(List<AddInfoDto> infoDtoList) {
        List<XjrInterfaceInfo> infoList = new ArrayList<>();
        List<XjrInterfaceParams> paramsList = new ArrayList<>();
        List<XjrInterfaceOutput> outputList = new ArrayList<>();
        for (AddInfoDto addInfoDto : infoDtoList) {
            String infoId = IdWorker.get32UUID();
            XjrInterfaceInfo info = BeanUtil.copy(addInfoDto, XjrInterfaceInfo.class);
            info.setId(infoId);
            // 输入参数
            List<AddParamDto> params = addInfoDto.getParams();
            if (CollectionUtil.isNotEmpty(params)) {
                for (AddParamDto paramDto : params) {
                    XjrInterfaceParams param = BeanUtil.copy(paramDto, XjrInterfaceParams.class);
                    param.setInfoId(infoId);
                    paramsList.add(param);
                }
            }
            // 输出参数
            List<AddOutputDto> outputs = addInfoDto.getOutputs();
            if (CollectionUtil.isNotEmpty(outputs)) {
                for (AddOutputDto outputDto : outputs) {
                    XjrInterfaceOutput output = BeanUtil.copy(outputDto, XjrInterfaceOutput.class);
                    output.setInfoId(infoId);
                    outputList.add(output);
                }
            }
            infoList.add(info);
        }
        paramsService.saveBatch(paramsList);
        outputService.saveBatch(outputList);
        return this.saveBatch(infoList);
    }

    /**
     * @Author: tzx
     * @Description: 执行根据接口管理配置 执行post请求
     * @Date: 2022-01-24 15:33
     */
    @Override
    public Response executePut(XjrInterfaceInfo info, List<XjrInterfaceParams> paramsList, List<XjrInterfaceOutput> outputList, Map<String, String> paramMap, HttpServletRequest request) {
        MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
        OkHttpClient client = new OkHttpClient();
        String host = "";
        boolean isInternal = true; // 是否为内部接口
        // isinternal == 0  就是内部接口  内部接口 默认拼接当前请求的 ip:port
        if (info.getIsInternal() == 0) {
            //获取到当前请求的host 用于套娃请求
            host = serverConfig.getLocalUrl();
        } else {
            isInternal = false;
        }
        HttpUrl parse = HttpUrl.parse(host + info.getUrlAddress());
        if (parse == null) {
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: 当前接口请求地址:" + host + info.getUrlAddress() + "错误！";
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求地址:" + host + info.getUrlAddress() + "错误！");
        }
        HttpUrl.Builder builder = Objects.requireNonNull(parse).newBuilder();
        Map<String, String> paramsMap = new HashMap<>();

        //拼接querystring 和 body 从参数
        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            //从传入参数获取值
            String value = paramMap.get(xjrInterfaceParams.getParamKey());

            //get请求没有body  如果参数设置为body  也是改为querystring
            if (xjrInterfaceParams.getType() == 1) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    paramsMap.put(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    paramsMap.put(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }

            } else if (xjrInterfaceParams.getType() == 2) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }
            }
        }

        Request.Builder url = new Request.Builder().url(builder.build());
        //内部接口才需要使用原有hearder
        if (isInternal) {
            Enumeration<String> headers = request.getHeaderNames();
            while (headers.hasMoreElements()) {
                String key = headers.nextElement();
                url.addHeader(key, request.getHeader(key));
            }
        }

        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            String value = paramMap.get(xjrInterfaceParams.getParamKey());
            //如果有header参数
            if (xjrInterfaceParams.getType() == 0) {
                String paramKey = xjrInterfaceParams.getParamKey();
                String paramValue = xjrInterfaceParams.getParamValue();
                String headerValue = request.getHeader(paramKey);
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    url.addHeader(paramKey, value);
                } else if(StringUtil.isNotBlank(headerValue)) {
                    url.addHeader(paramKey, headerValue);
                }else {  //如果没有传入参数 则用默认参数
                    url.addHeader(paramKey,paramValue);
                }
            }
        }

        okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));
        Request req = url.put(body).build();

        try (okhttp3.Response response = client.newCall(req).execute()) {
            String responseBody = Objects.requireNonNull(response.body()).string();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            if (!response.isSuccessful()) {
                // ... handle failed request
                String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+responseBody;
                addLog(-1, info.getName(), endMessage);
                return Response.notOk("当前接口请求错误！错误原因: "+responseBody );
            }

            // ... do something with response
            if (jsonObject != null) {
                //如果是内部接口  则是默认的返回格式  直接取data里面的数据
                if (isInternal) {
                    Integer code = (Integer) jsonObject.get("code");
                    if (code == 0) {
                        Map<String, Object> resultMap = new HashMap<>();

                        //如果没有配置返回值  默认使用data
                        if (outputList.size() == 0) {
                            return Response.ok(jsonObject.get("data"));
                        }
                        JSONObject data = jsonObject.getJSONObject("data");
                        for (XjrInterfaceOutput output : outputList) {
                            resultMap.put(output.getOutputKey(), data.get(output.getOutputKey()));
                        }
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                        addLog(1, info.getName(), endMessage);
                        return Response.ok(resultMap);
                    } else {
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+responseBody;
                        addLog(-1, info.getName(), endMessage);
                        return Response.notOk(code, "当前接口请求错误,错误原因: "+responseBody);
                    }
                } else { //如果是外部接口
                    Map<String, Object> resultMap = new HashMap<>();
                    for (XjrInterfaceOutput output : outputList) {
                        String resultKey = output.getResultKey();
                        String[] keyArray = resultKey.split(".");

                        //如果多级
                        if (keyArray.length > 1) {
                            JSONObject data = null;

                            for (int i = 0; i < keyArray.length; i++) {
                                //第一次从 jsonobject取
                                if (i == 0) {
                                    data = jsonObject.getJSONObject(keyArray[i]);
                                }
                                // 如果是最后一级 默认使用 get()  不能使用 getJsonobject
                                if (i == keyArray.length - 1) {
                                    resultMap.put(output.getOutputKey(), data.get(resultKey));
                                }
                                //不是最后一级  使用getjsonobject
                                else {
                                    data = data.getJSONObject(keyArray[i]);
                                }

                            }

                        }
                        //如果只有一级
                        else {
                            resultMap.put(output.getOutputKey(), jsonObject.get(resultKey));
                        }
                    }
                    String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                    addLog(1, info.getName(), endMessage);
                    Set<Map.Entry<String, Object>> entries = resultMap.entrySet();
                    for (Map.Entry<String, Object> entry : entries) {
                        Object value = entry.getValue();
                        String reg4 = "^[0-9]+(.[0-9]+)?$";
                        String valueStr= String.valueOf(value);
                        if(Pattern.matches(reg4, valueStr)){
                            //为数字格式
                            entry.setValue(Integer.valueOf(valueStr));
                        }
                    }
                    return Response.ok(resultMap);
                }
            }
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败,失败原因: "+responseBody;
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因: "+responseBody);
        } catch (IOException e) {
            // ... handle IO exception
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败,失败原因:" + e.getMessage();
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因: "+e.getMessage());
        }
    }

    /**
     * @Author: tzx
     * @Description: 执行根据接口管理配置 执行post请求
     * @Date: 2022-01-24 15:33
     */
    @Override
    public Response executeDelete(XjrInterfaceInfo info, List<XjrInterfaceParams> paramsList, List<XjrInterfaceOutput> outputList, Map<String, String> paramMap, HttpServletRequest request) {
        MediaType JSONType = MediaType.parse(org.springframework.http.MediaType.APPLICATION_JSON_VALUE);
        OkHttpClient client = new OkHttpClient();
        String host = "";
        boolean isInternal = true; // 是否为内部接口
        // isinternal == 0  就是内部接口  内部接口 默认拼接当前请求的 ip:port
        if (info.getIsInternal() == 0) {
            //获取到当前请求的host 用于套娃请求
            host = serverConfig.getLocalUrl();
        } else {
            isInternal = false;
        }

        HttpUrl parse = HttpUrl.parse(host + info.getUrlAddress());
        if (parse == null) {
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: 当前接口请求地址:" + host + info.getUrlAddress() + "错误！";
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求地址:" + host + info.getUrlAddress() + "错误！");
        }
        HttpUrl.Builder builder = Objects.requireNonNull(parse).newBuilder();

        Map<String, String> paramsMap = new HashMap<>();

        //拼接querystring 和 body 从参数
        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            //从传入参数获取值
            String value = paramMap.get(xjrInterfaceParams.getParamKey());

            //get请求没有body  如果参数设置为body  也是改为querystring
            if (xjrInterfaceParams.getType() == 1) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    paramsMap.put(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    paramsMap.put(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }

            } else if (xjrInterfaceParams.getType() == 2) {
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), value);
                } else { //如果没有传入参数 则用默认参数
                    builder.addQueryParameter(xjrInterfaceParams.getParamKey(), xjrInterfaceParams.getParamValue());
                }
            }
        }

        Request.Builder url = new Request.Builder().url(builder.build());
        //内部接口才需要使用原有hearder
        if (isInternal) {
            Enumeration<String> headers = request.getHeaderNames();
            while (headers.hasMoreElements()) {
                String key = headers.nextElement();
                url.addHeader(key, request.getHeader(key));
            }
        }

        for (XjrInterfaceParams xjrInterfaceParams : paramsList) {
            String value = paramMap.get(xjrInterfaceParams.getParamKey());
            //如果有header参数
            if (xjrInterfaceParams.getType() == 0) {
                String paramKey = xjrInterfaceParams.getParamKey();
                String paramValue = xjrInterfaceParams.getParamValue();
                String headerValue = request.getHeader(paramKey);
                //如果传入参数  则用传入的参数
                if (StringUtil.isNotBlank(value)) {
                    url.addHeader(paramKey, value);
                } else if(StringUtil.isNotBlank(headerValue)) {
                    url.addHeader(paramKey, headerValue);
                }else {  //如果没有传入参数 则用默认参数
                    url.addHeader(paramKey,paramValue);
                }
            }
        }

        okhttp3.RequestBody body = okhttp3.RequestBody.create(JSONType, JSON.toJSONString(paramsMap));

        Request req = url.delete(body).build();

        try (okhttp3.Response response = client.newCall(req).execute()) {
            String responseBody = Objects.requireNonNull(response.body()).string();
            JSONObject jsonObject = JSONObject.parseObject(responseBody);
            if (!response.isSuccessful()) {
                // ... handle failed request
                String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+responseBody;
                addLog(-1, info.getName(), endMessage);
                return Response.notOk("当前接口请求错误！错误原因: "+responseBody);
            }

            // ... do something with response
            if (jsonObject != null) {
                //如果是内部接口  则是默认的返回格式  直接取data里面的数据
                if (isInternal) {
                    Integer code = (Integer) jsonObject.get("code");
                    if (code == 0) {

                        Map<String, Object> resultMap = new HashMap<>();

                        //如果没有配置返回值  默认使用data
                        if (outputList.size() == 0) {
                            return Response.ok(jsonObject.get("data"));
                        }

                        JSONObject data = jsonObject.getJSONObject("data");
                        for (XjrInterfaceOutput output : outputList) {
                            resultMap.put(output.getOutputKey(), data.get(output.getOutputKey()));
                        }
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                        addLog(1, info.getName(), endMessage);
                        return Response.ok(resultMap);
                    } else {
                        String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: "+responseBody;
                        addLog(-1, info.getName(), endMessage);
                        return Response.notOk("当前接口请求错误！错误原因: "+responseBody);
                    }
                } else { //如果是外部接口
                    Map<String, Object> resultMap = new HashMap<>();
                    for (XjrInterfaceOutput output : outputList) {
                        String resultKey = output.getResultKey();
                        String[] keyArray = resultKey.split(".");

                        //如果多级
                        if (keyArray.length > 1) {
                            JSONObject data = null;

                            for (int i = 0; i < keyArray.length; i++) {
                                //第一次从 jsonobject取
                                if (i == 0) {
                                    data = jsonObject.getJSONObject(keyArray[i]);
                                }
                                // 如果是最后一级 默认使用 get()  不能使用 getJsonobject
                                if (i == keyArray.length - 1) {
                                    resultMap.put(output.getOutputKey(), data.get(resultKey));
                                }
                                //不是最后一级  使用getjsonobject
                                else {
                                    data = data.getJSONObject(keyArray[i]);
                                }

                            }

                        }
                        //如果只有一级
                        else {
                            resultMap.put(output.getOutputKey(), jsonObject.get(resultKey));
                        }
                    }
                    String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行成功";
                    addLog(1, info.getName(), endMessage);
                    Set<Map.Entry<String, Object>> entries = resultMap.entrySet();
                    for (Map.Entry<String, Object> entry : entries) {
                        Object value = entry.getValue();
                        String reg4 = "^[0-9]+(.[0-9]+)?$";
                        String valueStr= String.valueOf(value);
                        if(Pattern.matches(reg4, valueStr)){
                            //为数字格式
                            entry.setValue(Integer.valueOf(valueStr));
                        }
                    }
                    return Response.ok(resultMap);
                }
            }
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败,失败原因: "+responseBody;
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因: "+responseBody);


        } catch (IOException e) {
            String endMessage = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + info.getName() + StringPool.RIGHT_SQ_BRACKET + "执行失败，失败原因: " + e.getMessage();
            addLog(-1, info.getName(), endMessage);
            return Response.notOk("当前接口请求错误！错误原因: "+e.getMessage());
        }
    }


    /**
     * @Author: tzx
     * @Description: 检查自定义接口参数
     * @Date: 2022-01-27 10:21
     */
    public Boolean checkCustomizeParamValue(JSONArray paramsList, Map<String, String> inputMap, boolean checkParamNodeLog, String interfaceName) {
        //先检查参数是否合格
        if (checkParamNodeLog) {
            String message = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + interfaceName + StringPool.RIGHT_SQ_BRACKET + "[验证接口参数]执行开始";
            addLog(1, interfaceName, message);
        }
        for (int i = 0; i < paramsList.size(); i++) {
            JSONObject paramsObj = paramsList.getJSONObject(i);
            String key = paramsObj.getString(SchemaConst.PARAM_KEY);
            String value = inputMap.get(key);
            Integer volidate = paramsObj.getInteger(SchemaConst.PARAM_VOLIDATE);
            //如果有传入参数 就必须要验证  如果没有参数 则使用默认值  就不需要验证了  前端设置默认值的时候就做好验证
            if (!StringUtil.isEmpty(value)) {
                if (volidate == null || checkValue(volidate, value)) {
                    continue;
                } else {
                    if (checkParamNodeLog) {
                        String message = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + interfaceName + StringPool.RIGHT_SQ_BRACKET + "[验证接口参数]执行失败,失败原因: " + key + "参数校验不通过";
                        addLog(-1, interfaceName, message);
                    }
                    return false;
                }
            }
        }
        if (checkParamNodeLog) {
            String message = LocalDateTime.now() + StringPool.LEFT_SQ_BRACKET + interfaceName + StringPool.RIGHT_SQ_BRACKET + "[验证接口参数]执行结束";
            addLog(1, interfaceName, message);
        }
//        logService.addLog()
        return true;
    }


    /**
     * @Author: tzx
     * @Description: 根据前端输入的type  验证参数
     * @Date: 2022-02-08 16:28
     */
    public Boolean checkValue(Integer type, String value) {
        switch (type) {
            //不能为空
            case 0:
            case 1:
                return StringUtil.isNotBlank(value);
            //仅为数字
            case 2:
                return StringUtil.isNumeric(value);
            //仅为数字，且不能为0
            case 3:
                return StringUtil.isNumeric(value) && !StringUtil.equals("0", value);
            //仅为数字包含小数 可以为0
            case 4:
            //仅为数字包含小数，且不能为0
                String reg4 = "^[0-9]+(.[0-9]+)?$";
                return Pattern.matches(reg4, value);
            case 5:
                String reg5 = "^[0-9]+(.[0-9]+)?$";
                return Pattern.matches(reg5, value) && !StringUtil.equals("0", value);
            //仅为电话
            case 6:
                String reg6 = "^[0-9]*$";
                return Pattern.matches(reg6, value) || StringUtil.isEmpty(value);
            //仅为电话
            case 7:
                String reg7 = "^[0-9]*$";
                return Pattern.matches(reg7, value) && StringUtil.isNotBlank(value);
            //仅为手机 可以为空
            case 8:
                String reg8 = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\\\d{8}$";
                return Pattern.matches(reg8, value) || StringUtil.isEmpty(value);
            //仅为手机
            case 9:
                String reg9 = "^((13[0-9])|(14[5,7])|(15[0-3,5-9])|(17[0,3,5-8])|(18[0-9])|166|198|199|(147))\\\\d{8}$";
                return Pattern.matches(reg9, value) && StringUtil.isNotBlank(value);
            //仅为邮箱 可以为空
            case 10:
                String reg10 = "^([a-z0-9A-Z]+[-|//.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?//.)+[a-zA-Z]{2,}$";
                return Pattern.matches(reg10, value) || StringUtil.isEmpty(value);
            //仅为邮箱
            case 11:
                String reg11 = "^([a-z0-9A-Z]+[-|//.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?//.)+[a-zA-Z]{2,}$";
                return Pattern.matches(reg11, value) && StringUtil.isNotBlank(value);
            default:
                return true;
        }
    }

    /**
     * @Author: tzx
     * @Description: 替换sql  将里面的占位符替换为变量值 或者参数值
     * @Date: 2022-02-14 16:28
     */
    public String replaceSqlParam(String oldSql, Map<String, String> paramMap, Map<String, Object> varMap) {
        String newSql = oldSql;

        for (Map.Entry<String, String> param : paramMap.entrySet()) {
            String replaceFlag = "接口入参." + param.getKey();

            newSql = newSql.replace(replaceFlag, param.getValue());
        }

        for (Map.Entry<String, Object> var : varMap.entrySet()) {
            String replaceFlag = "接口变量." + var.getKey();

            newSql = newSql.replace(replaceFlag, String.valueOf(var.getValue()));
        }

        if (newSql.contains("系统时间.")) {
            if (newSql.contains("系统时间.yyyy-MM-dd HH:mm:ss")) {
                DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                newSql = newSql.replace("系统时间.yyyy-MM-dd HH:mm:ss", LocalDateTime.now().format(format0));
            }
            if (newSql.contains("系统时间.yyyy-MM-dd hh:mm:ss")) {
                DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
                newSql = newSql.replace("系统时间.yyyy-MM-dd hh:mm:ss", LocalDateTime.now().format(format0));
            }
            if (newSql.contains("系统时间.yyyy-MM-dd")) {
                DateTimeFormatter format0 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
                newSql = newSql.replace("系统时间.yyyy-MM-dd", LocalDateTime.now().format(format0));
            }
            if (newSql.contains("系统时间.HH:mm:ss")) {
                DateTimeFormatter format0 = DateTimeFormatter.ofPattern("HH:mm:ss");
                newSql = newSql.replace("系统时间.HH:mm:ss", LocalDateTime.now().format(format0));
            }
            if (newSql.contains("系统时间.hh:mm:ss")) {
                DateTimeFormatter format0 = DateTimeFormatter.ofPattern("hh:mm:ss");
                newSql = newSql.replace("系统时间.hh:mm:ss", LocalDateTime.now().format(format0));
            }
        }


        return newSql;
    }


    /**
     * @Author: tzx
     * @Description: 检查参数
     * @Date: 2022-01-27 10:21
     */
    public Boolean checkParamValue(List<XjrInterfaceParams> paramsList, Map<String, String> inputMap) {
        //先检查参数是否合格
        for (XjrInterfaceParams param : paramsList) {
            String value = inputMap.get(param.getParamKey());

            //如果有传入参数 就必须要验证  如果没有参数 则使用默认值  就不需要验证了  前端设置默认值的时候就做好验证
            if (!StringUtil.isEmpty(value)) {
                //根据入参正则验证 值是否符合要求
                if (!StringUtil.isEmpty(param.getVolidate()) && !Pattern.matches(param.getVolidate(), value)) {
                    return false;
                }
            }
        }
        return true;
    }

    //添加日志信息
    private boolean addLog(Integer executeResult, String interfaceName, String message) {
        XjrBaseLog log = new XjrBaseLog();
        HttpServletRequest request = WebUtil.getRequest();
        assert request != null;
        log.setCategoryId(LogCategoryEnum.INTERFACE.getCode());
        log.setHost(request.getRemoteHost());
        log.setOperateTime(LocalDateTime.now());
        log.setIpAddress(IpUtil.getIpAddr(request));
        log.setOperateType(OperateTypeEnum.APIINVOKE.getValue());
        log.setOperateTypeId(Integer.toString(OperateTypeEnum.APIINVOKE.getCode()));
        log.setExecuteResult(executeResult);
        log.setDescription(message);
        log.setDescription(message);
        log.setBrowser(LogUtil.getBrowser((request.getHeader("user-agent"))));
        log.setModule(interfaceName);
        log.setOperateAccount(SecureUtil.getUserAccount());
        log.setOperateUserId(SecureUtil.getUserId());
        return logService.addLog(log);
    }
}
